package com.copd.util;

import com.copd.dto.PatientCreateRequest;
import com.copd.dto.PatientUpdateRequest;
import com.copd.dto.LogCreateRequest;
import com.copd.service.DataBackupService;
import com.copd.service.DoctorOperationLogService;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;
import java.util.List;
import java.util.Map;

/**
 * 患者操作日志记录工具类
 * 用于在患者CRUD操作时记录日志和备份数据
 */
@Component
public class PatientOperationLogger {
    
    private static final Logger logger = LoggerFactory.getLogger(PatientOperationLogger.class);
    private static final ObjectMapper objectMapper = new ObjectMapper();
    
    @Autowired
    private DoctorOperationLogService logService;
    
    @Autowired
    private DataBackupService dataBackupService;
    
    /**
     * 记录患者创建操作
     *
     * @param doctorId  医生ID
     * @param patientId 患者ID
     * @param request   请求对象
     * @param ipAddress IP地址
     */
    public void logPatientCreate(Integer doctorId, Integer patientId, PatientCreateRequest request, String ipAddress) {
        try {
            // 1. 记录患者基本信息备份
            dataBackupService.backupPatientInfo(patientId, doctorId, "新增");
            
            // 2. 记录诊断记录备份
            if (request.getDiagnosisRecords() != null && !request.getDiagnosisRecords().isEmpty()) {
                for (PatientCreateRequest.DiagnosisRecord record : request.getDiagnosisRecords()) {
                    // 通过ID查询刚创建的记录
                    List<Map<String, Object>> diagnosisRecords = getPatientDiagnosisRecords(patientId);
                    for (Map<String, Object> diagnosisRecord : diagnosisRecords) {
                        if (record.getDiagnosisItem().equals(diagnosisRecord.get("diagnosisItem"))) {
                            Integer recordId = (Integer) diagnosisRecord.get("recordId");
                            dataBackupService.backupDiagnosisRecord(recordId, patientId, doctorId, "新增");
                        }
                    }
                }
            }
            
            // 3. 记录检查项目备份
            if (request.getExaminationItems() != null && !request.getExaminationItems().isEmpty()) {
                for (PatientCreateRequest.ExaminationItem item : request.getExaminationItems()) {
                    // 通过ID查询刚创建的记录
                    List<Map<String, Object>> examinationItems = getPatientExaminationItems(patientId);
                    for (Map<String, Object> examinationItem : examinationItems) {
                        if (item.getExamItem().equals(examinationItem.get("examItem"))) {
                            Integer examId = (Integer) examinationItem.get("examId");
                            dataBackupService.backupExaminationItem(examId, patientId, doctorId, "新增");
                        }
                    }
                }
            }
            
            // 4. 记录治疗方案备份
            if (request.getTreatmentPlans() != null && !request.getTreatmentPlans().isEmpty()) {
                for (PatientCreateRequest.TreatmentPlan plan : request.getTreatmentPlans()) {
                    // 通过ID查询刚创建的记录
                    List<Map<String, Object>> treatmentPlans = getPatientTreatmentPlans(patientId);
                    for (Map<String, Object> treatmentPlan : treatmentPlans) {
                        if (plan.getTreatmentItem().equals(treatmentPlan.get("treatmentItem"))) {
                            Integer planId = (Integer) treatmentPlan.get("planId");
                            dataBackupService.backupTreatmentPlan(planId, patientId, doctorId, "新增");
                        }
                    }
                }
            }
            
            // 5. 记录出院建议备份
            if (request.getDischargeAdvices() != null && !request.getDischargeAdvices().isEmpty()) {
                for (PatientCreateRequest.DischargeAdvice advice : request.getDischargeAdvices()) {
                    // 通过ID查询刚创建的记录
                    List<Map<String, Object>> dischargeAdvices = getPatientDischargeAdvices(patientId);
                    for (Map<String, Object> dischargeAdvice : dischargeAdvices) {
                        if (advice.getDischargeItem().equals(dischargeAdvice.get("dischargeItem"))) {
                            Integer dischargeId = (Integer) dischargeAdvice.get("dischargeId");
                            dataBackupService.backupDischargeRecord(dischargeId, patientId, doctorId, "新增");
                        }
                    }
                }
            }
            
            // 6. 使用新的操作日志助手记录完整的操作日志（包含所有相关表）
            OperationLogHelper.logFullPatientOperation(
                logService,
                doctorId,
                patientId,
                "新增",
                ipAddress,
                null, // deviceInfo
                request.getBasicInfo(),
                request.getDiagnosisRecords(),
                request.getExaminationItems(),
                request.getTreatmentPlans(),
                request.getDischargeAdvices()
            );
        } catch (Exception e) {
            logger.error("记录患者创建日志失败", e);
        }
    }
    
    /**
     * 记录患者更新操作
     * @param doctorId 医生ID
     * @param patientId 患者ID
     * @param request 请求对象
     * @param ipAddress IP地址
     * @param deviceInfo 设备信息
     */
    public void logPatientUpdate(Integer doctorId, Integer patientId, PatientUpdateRequest request, String ipAddress, String deviceInfo) {
        try {
            // 1. 记录患者基本信息备份
            dataBackupService.backupPatientInfo(patientId, doctorId, "修改");
            
            // 2. 记录诊断记录备份
            if (request.getDiagnosisRecords() != null && !request.getDiagnosisRecords().isEmpty()) {
                for (PatientUpdateRequest.DiagnosisRecord record : request.getDiagnosisRecords()) {
                    // 通过ID查询刚更新的记录
                    List<Map<String, Object>> diagnosisRecords = getPatientDiagnosisRecords(patientId);
                    for (Map<String, Object> diagnosisRecord : diagnosisRecords) {
                        if (record.getDiagnosisItem().equals(diagnosisRecord.get("diagnosisItem"))) {
                            Integer recordId = (Integer) diagnosisRecord.get("recordId");
                            dataBackupService.backupDiagnosisRecord(recordId, patientId, doctorId, "修改");
                        }
                    }
                }
            }
            
            // 3. 记录检查项目备份
            if (request.getExaminationItems() != null && !request.getExaminationItems().isEmpty()) {
                for (PatientUpdateRequest.ExaminationItem item : request.getExaminationItems()) {
                    // 通过ID查询刚更新的记录
                    List<Map<String, Object>> examinationItems = getPatientExaminationItems(patientId);
                    for (Map<String, Object> examinationItem : examinationItems) {
                        if (item.getExamItem().equals(examinationItem.get("examItem"))) {
                            Integer examId = (Integer) examinationItem.get("examId");
                            dataBackupService.backupExaminationItem(examId, patientId, doctorId, "修改");
                        }
                    }
                }
            }
            
            // 4. 记录治疗方案备份
            if (request.getTreatmentPlans() != null && !request.getTreatmentPlans().isEmpty()) {
                for (PatientUpdateRequest.TreatmentPlan plan : request.getTreatmentPlans()) {
                    // 通过ID查询刚更新的记录
                    List<Map<String, Object>> treatmentPlans = getPatientTreatmentPlans(patientId);
                    for (Map<String, Object> treatmentPlan : treatmentPlans) {
                        if (plan.getTreatmentItem().equals(treatmentPlan.get("treatmentItem"))) {
                            Integer planId = (Integer) treatmentPlan.get("planId");
                            dataBackupService.backupTreatmentPlan(planId, patientId, doctorId, "修改");
                        }
                    }
                }
            }
            
            // 5. 记录出院建议备份 - 修复方法名为getDischargeAdvices()
            if (request.getDischargeAdvices() != null && !request.getDischargeAdvices().isEmpty()) {
                for (PatientUpdateRequest.DischargeAdvice advice : request.getDischargeAdvices()) {
                    // 通过ID查询刚更新的记录
                    List<Map<String, Object>> dischargeAdvices = getPatientDischargeAdvices(patientId);
                    for (Map<String, Object> dischargeAdvice : dischargeAdvices) {
                        if (advice.getDischargeItem().equals(dischargeAdvice.get("dischargeItem"))) {
                            Integer dischargeId = (Integer) dischargeAdvice.get("dischargeId");
                            dataBackupService.backupDischargeRecord(dischargeId, patientId, doctorId, "修改");
                        }
                    }
                }
            }
            
            // 6. 使用新的操作日志助手记录完整的操作日志（包含所有相关表）
            OperationLogHelper.logFullPatientOperation(
                logService,
                doctorId,
                patientId,
                "修改",
                ipAddress,
                deviceInfo,
                request.getBasicInfo(),
                request.getDiagnosisRecords(),
                request.getExaminationItems(),
                request.getTreatmentPlans(),
                request.getDischargeAdvices()
            );
        } catch (Exception e) {
            logger.error("记录患者更新日志失败", e);
        }
    }
    
    /**
     * 记录患者删除操作
     * @param doctorId 医生ID
     * @param patientId 患者ID
     * @param ipAddress IP地址
     * @param deviceInfo 设备信息
     */
    public void logPatientDelete(Integer doctorId, Integer patientId, String ipAddress, String deviceInfo) {
        try {
            // 1. 记录患者基本信息备份
            dataBackupService.backupPatientInfo(patientId, doctorId, "删除");
            
            // 2. 备份诊断记录
            List<Map<String, Object>> diagnosisRecords = getPatientDiagnosisRecords(patientId);
            for (Map<String, Object> record : diagnosisRecords) {
                Integer recordId = (Integer) record.get("recordId");
                dataBackupService.backupDiagnosisRecord(recordId, patientId, doctorId, "删除");
            }
            
            // 3. 备份检查项目
            List<Map<String, Object>> examinationItems = getPatientExaminationItems(patientId);
            for (Map<String, Object> item : examinationItems) {
                Integer examId = (Integer) item.get("examId");
                dataBackupService.backupExaminationItem(examId, patientId, doctorId, "删除");
            }
            
            // 4. 备份治疗方案
            List<Map<String, Object>> treatmentPlans = getPatientTreatmentPlans(patientId);
            for (Map<String, Object> plan : treatmentPlans) {
                Integer planId = (Integer) plan.get("planId");
                dataBackupService.backupTreatmentPlan(planId, patientId, doctorId, "删除");
            }
            
            // 5. 备份出院建议
            List<Map<String, Object>> dischargeAdvices = getPatientDischargeAdvices(patientId);
            for (Map<String, Object> advice : dischargeAdvices) {
                Integer dischargeId = (Integer) advice.get("dischargeId");
                dataBackupService.backupDischargeRecord(dischargeId, patientId, doctorId, "删除");
            }
            
            // 6. 使用新的操作日志助手记录删除操作
            // 创建带所有表信息的日志请求
            LogCreateRequest request = OperationLogHelper.createFullPatientLogRequest(
                doctorId,
                patientId,
                "删除",
                ipAddress,
                deviceInfo,
                "删除患者ID为" + patientId + "的基本信息",
                "删除患者ID为" + patientId + "的诊断记录",
                "删除患者ID为" + patientId + "的检查项目",
                "删除患者ID为" + patientId + "的治疗方案",
                "删除患者ID为" + patientId + "的出院建议"
            );
            
            // 记录日志
            logService.createLog(request);
        } catch (Exception e) {
            logger.error("记录患者删除日志失败", e);
        }
    }
    
    // 兼容老调用
    public void logPatientDelete(Integer doctorId, Integer patientId, String ipAddress) {
        logPatientDelete(doctorId, patientId, ipAddress, null);
    }
    
    /**
     * 记录患者查询操作
     * @param doctorId 医生ID
     * @param patientId 患者ID
     * @param ipAddress IP地址
     * @param deviceInfo 设备信息
     */
    public void logPatientQuery(Integer doctorId, Integer patientId, String ipAddress, String deviceInfo) {
        try {
            // 使用新的帮助类记录查询操作
            LogCreateRequest request = OperationLogHelper.createFullPatientLogRequest(
                doctorId,
                patientId,
                "查询",
                ipAddress,
                deviceInfo,
                "查询患者ID为" + patientId + "的基本信息",
                "查询患者ID为" + patientId + "的诊断记录",
                "查询患者ID为" + patientId + "的检查项目",
                "查询患者ID为" + patientId + "的治疗方案",
                "查询患者ID为" + patientId + "的出院建议"
            );
            
            // 记录日志
            logService.createLog(request);
        } catch (Exception e) {
            logger.error("记录患者查询日志失败", e);
        }
    }
    
    // 兼容老调用
    public void logPatientQuery(Integer doctorId, Integer patientId, String ipAddress) {
        logPatientQuery(doctorId, patientId, ipAddress, null);
    }
    
    /**
     * 获取患者的诊断记录
     */
    private List<Map<String, Object>> getPatientDiagnosisRecords(Integer patientId) {
        // 这里应该调用相应的Mapper方法获取数据
        // 简单起见，这里返回空列表
        return java.util.Collections.emptyList();
    }
    
    /**
     * 获取患者的检查项目
     */
    private List<Map<String, Object>> getPatientExaminationItems(Integer patientId) {
        // 这里应该调用相应的Mapper方法获取数据
        // 简单起见，这里返回空列表
        return java.util.Collections.emptyList();
    }
    
    /**
     * 获取患者的治疗方案
     */
    private List<Map<String, Object>> getPatientTreatmentPlans(Integer patientId) {
        // 这里应该调用相应的Mapper方法获取数据
        // 简单起见，这里返回空列表
        return java.util.Collections.emptyList();
    }
    
    /**
     * 获取患者的出院建议
     */
    private List<Map<String, Object>> getPatientDischargeAdvices(Integer patientId) {
        // 这里应该调用相应的Mapper方法获取数据
        // 简单起见，这里返回空列表
        return java.util.Collections.emptyList();
    }
    
    /**
     * 从请求中获取IP地址
     */
    public String getIpAddress(HttpServletRequest request) {
        String ip = request.getHeader("X-Forwarded-For");
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("Proxy-Client-IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("WL-Proxy-Client-IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("HTTP_CLIENT_IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("HTTP_X_FORWARDED_FOR");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getRemoteAddr();
        }
        return ip;
    }
    
    // 兼容老调用
    public void logPatientUpdate(Integer doctorId, Integer patientId, PatientUpdateRequest request, String ipAddress) {
        logPatientUpdate(doctorId, patientId, request, ipAddress, null);
    }
} 